#include <sqlite3.h>
#include <stdio.h>

//该查询用于获取 SQLite 库的版本。SQLITE_VERSION()
/*
	我们使用 GNU C 编译器编译程序。
	gcc -o version version.c -lsqlite3
	
	./version2
*/

int main(void)
{
    //该结构定义数据库句柄。每个打开的 SQLite 数据库都由一个数据库句柄表示。sqlite3
    sqlite3 *db;

    //该结构表示单个 SQL 语句。sqlite3_stmt
    sqlite3_stmt *res;

   // 该函数将打开一个新的数据库连接。其参数是数据库名称和数据库句柄。
   //是一个特殊的数据库名称，使用该名称可打开内存中数据库。
   //该函数的返回代码指示数据库是否已成功打开。成功建立连接时返回 。
   //sqlite3_open():memory:SQLITE_OK
   
    int rc = sqlite3_open(":memory:", &db);

	/*
		如果返回代码指示错误，我们将消息打印到控制台，关闭数据库句柄，然后终止程序。
		该函数返回错误的描述。
		无论打开数据库连接句柄时是否发生错误，
		都应通过将其传递到函数来释放与数据库连接句柄关联的资源。
		sqlite3_errmsg()sqlite3_close()
	*/

    if (rc != SQLITE_OK) {
        
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        
        return 1;
    }

    rc = sqlite3_prepare_v2(db, "SELECT SQLITE_VERSION()", -1, &res, 0);    
	//sqlite3_prepare_v2各参数作用（创建一个SQL语句对象）：
	/*
		参数1:	数据库链接对象
		参数2:	指向原始的SQL语句 
		参数3: 	原始SQL语句的长度（原始SQL语句可以包含多条语句），需要指定编译SQL语句到那个位置
                < 0 编译SQL语句到第一个\0结束
		参数4:	二级指针，保存编译好的SQL语句对象
		参数5:	如果不为NULL，则pzTail指向SQL语句 未被使用的部分
				仅编译 SQL 字符串的第一个语句，因此参数指向未编译的内容。
				我们传递 0，因为参数对我们并不重要。
    */

    
    if (rc != SQLITE_OK) {
        
        fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        
        return 1;
    }  
    
    //执行SQL语句对象,我们的 SQL 语句只返回一行数据，因此，我们只调用此函数一次
    rc = sqlite3_step(res);
    
    if (rc == SQLITE_ROW) {
        printf("%s\n", sqlite3_column_text(res, 0));
    }


    //销毁SQL语句对象
    sqlite3_finalize(res);

    //关闭一个数据库链接对象
    sqlite3_close(db);
    
    return 0;
}

